﻿using System;
using System.DirectoryServices;
using System.Text;
using System.IO;

namespace ConsoleApplicationAD
{
    /** 
     * L' avviso al Fleet (S.Brunetti) che la gestione 
     * delle macchine in trasferimento su AD Risorse diventa
     * fondamentale è in carico alla L.Pirola (24.01.13) 
     * 
     * Sarà da realizzare l'aggiornamento del NAMES a valle 
     * di specifiche chiare dettate da Francesco Trocchia (24.01.13)
     */

    class Program
    {
        public static char env = 'p'; //p >> sta per produzione
        private static String version = "Aggiornamento contesto utente x AD - v1.0.0.beta - Autore: L.Dozio - data: 24.01.13";

        /** 
         * 0 >> ambiente p sta per produzione, c sta per collaudo
         * 1 >> log file con path
         */
        public static int Main(string[] args)
        {
            Console.WriteLine(version);
            StreamWriter writer = null;
            FileStream fs = null;
            String fileName = "updad.log"; 
            String userName = "";
            bool isAgrChn = false;
            if (args != null && args.Length > 0)
            {
                env = (args[0] != null) ? args[0].ToCharArray()[0] : 'c'; // >> sta per collaudo                                
                fileName = (args.Length > 1 && args[1] != null) ? args[1] : "updad.log";
            }
            if (env == 'c')
            {
                Console.Write("Inserisci l'utente (per attivare il recupero del utente di Environment >> invio) >>>");
                userName = Console.ReadLine();
            }//sulla produzione uso solo l'ENV USER
            else 
            {
                try
                {
                    //in produzione attivo il redirect su file della Console
                    //args[1]);
                    fs = new FileStream(fileName, FileMode.Create);
                    writer = new StreamWriter(fs);
                    // Redirect standard output from the console to the output file.
                    Console.SetOut(writer);
                }
                catch (IOException e)
                {
                    Console.WriteLine("Non è possibile creare il file di log: {0}", e.Message);
                    if (writer != null) writer.Close();
                    if (fs != null) fs.Close();
                }               
            }
            DirectoryEntry myResourcesLdapConnection = null;
            DirectoryEntry myAccountLdapConnection = null;
            String ouPc = "";
            try
            {
                myResourcesLdapConnection = createDirectoryEntry();
                DirectorySearcher searchPc = new DirectorySearcher(myResourcesLdapConnection);
                String computerName = System.Environment.GetEnvironmentVariable("COMPUTERNAME");
                if (computerName == null || "".Equals(computerName.Trim()))
                {
                    //è un problema e va segnalato
                    throw new Exception("Environment COMPUTERNAME non trovato! Non apporto alcuna modifica.");
                }
                searchPc.Filter = string.Format("(cn={0})", computerName.Trim());
                searchPc.PropertiesToLoad.Add("distinguishedName");
                SearchResult result = searchPc.FindOne();
                if (result != null)
                {
                    // create new object from search result
                    DirectoryEntry entryPc = result.GetDirectoryEntry();
                    /* show existing title
                    System.DirectoryServices.PropertyCollection pc = entryToUpdate.Properties;
                    foreach (string propName in pc.PropertyNames)
                    {
                        foreach (object value in entryToUpdate.Properties[propName])
                            Console.WriteLine("  property = {0}   value = {1}",
                               propName, value);
                    }*/
                    String dn = entryPc.Properties["distinguishedName"].Value.ToString();
                    //r14721 - 23.01.13: ELABORAZIONE del DN - (B: 
                    //format:dn:CN=C01165068,OU=0102948,OU=01Uffici,OU=01BPM,DC=resources,DC=bpmgrp,DC=global
                    isAgrChn = isAgrChannel(dn);
                    String bancaou = dn.Split(',')[1];                    
                    //Console.WriteLine("bancaou:{0}", bancaou);
                    ouPc = bancaou.Substring(5);
                    Console.WriteLine("Dal dn:{0} della macchina estraggo l'ou di appartenza {1}", dn, ouPc);
                    //Console.WriteLine("ouPc:{0}", ouPc);
                    //r14721 - 23.01.13: ELABORAZIONE del DN - :E)
                }                 
                else
                {
                    //Console.WriteLine("{0} non trovato!", computerName);
                    throw new Exception(string.Format("{0} non trovato! Non apporto alcuna modifica.", computerName));
                }
                //r14721 - 23.01.13: 
                //E' necessario che lo script elabori solo se la struttura utente o macchina, devo ancora capire, appartiene al mM.            
                //Aggiungo qui la verifica di appartenenza al mM: se si vado ad elaborare l'utente
                //se no non lo elaboro - (B:
                //24.01.13 - L. Pirola: richista causa gestione trasferimento immediato di abilitare la cosa per il canale Agenzia
                /*bool isPcInHS = isAgrChannel("00001"); //TODO rimuovere cablatura
                Console.WriteLine("Is PC in Ou H&S? {0}", isPcInHS);*/
                //r14721 - 23.01.13 - :E)
                if (isAgrChn)
                {
                    myAccountLdapConnection = createAccountDirectoryEntry();
                    DirectorySearcher searchUser = new DirectorySearcher(myAccountLdapConnection);
                    if ("".Equals(userName.Trim()))
                        userName = System.Environment.GetEnvironmentVariable("USERNAME");
                    if (userName == null || "".Equals(userName.Trim()))
                    {
                        //è un problema e va segnalato
                        throw new Exception("Environment USERNAME non trovato! Non apporto alcuna modifica.");
                    }
                    searchUser.Filter = string.Format("(sAMAccountName={0})", userName.Trim());
                    searchUser.PropertiesToLoad.Add("title");
                    searchUser.PropertiesToLoad.Add("extensionAttribute13");
                    SearchResult resultUid = searchUser.FindOne();
                    if (resultUid != null)
                    {
                        // create new object from search result
                        bool isUpdateNedeed = false;
                        DirectoryEntry entryToUpdate = resultUid.GetDirectoryEntry();
                        /* show existing title
                        System.DirectoryServices.PropertyCollection pc = entryToUpdate.Properties;
                        foreach (string propName in pc.PropertyNames)
                        {
                            foreach (object value in entryToUpdate.Properties[propName])
                                Console.WriteLine("  property = {0}   value = {1}",
                                   propName, value);
                        }*/
                        String title = entryToUpdate.Properties["title"].Value.ToString();
                        //Console.WriteLine("title:{0}", title);
                        if (!title.StartsWith(ouPc))
                        {
                            StringBuilder newTitle = new StringBuilder(ouPc).Append(title.Substring(title.IndexOf('/')));
                            title = newTitle.ToString();
                            entryToUpdate.Properties["title"].Value = title;
                            isUpdateNedeed = true;
                            //Console.WriteLine("tmp1:{0}", title);
                        }
                        if (entryToUpdate.Properties["extensionAttribute13"] != null)
                        {
                            //Console.WriteLine("tmp1,5:[{0}]", entryToUpdate.Properties["extensionAttribute13"].Value);
                            if (entryToUpdate.Properties["extensionAttribute13"].Value != null)
                            {
                                if (!entryToUpdate.Properties["extensionAttribute13"].Value.ToString().Equals(ouPc))
                                {
                                    entryToUpdate.Properties["extensionAttribute13"].Value = ouPc;
                                    isUpdateNedeed = true;
                                    //Console.WriteLine("tmp2:{0}", ouPc);
                                }
                            }
                            else
                            {
                                entryToUpdate.Properties["extensionAttribute13"].Value = ouPc;
                                isUpdateNedeed = true;
                                //Console.WriteLine("tmp3:{0}", ouPc);                            
                            }
                        }//else non dovrebbe mai avvenire                      
                        if (isUpdateNedeed)
                        {
                            entryToUpdate.CommitChanges();
                            Console.WriteLine("Per l'utente {0} title e extensionAttribute13 sono aggiornati: {1} e {2}", userName, title, ouPc);
                        }
                        else 
                        {
                            Console.WriteLine("Le configurazione per l'utente {0} non hanno richiesto aggiornamenti", userName);
                        }
                    }
                    else
                    {
                        //Console.WriteLine("{0} non trovato!", userName);
                        throw new Exception(string.Format("{0} non trovato! Non apporto alcuna modifica.", userName));
                    }
                }
                else 
                {
                    Console.WriteLine("La macchina dell'utente non risulta del canale Agenzia di BPM");
                    return 0; //operatività corretta
                }
            }

            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                return -1;
            }
            finally {
                if (myResourcesLdapConnection != null) myResourcesLdapConnection.Close();
                if (myAccountLdapConnection != null) myAccountLdapConnection.Close();
                if (writer != null)
                {
                    writer.Flush();
                    writer.Close();
                }
                if (fs != null) fs.Close();
            }            
            return 0;
        }

        static DirectoryEntry createDirectoryEntry()
        {            
            // create and return new LDAP connection with desired settings
            DirectoryEntry ldapConnection     = new DirectoryEntry();
            //Console.WriteLine(env);
            ldapConnection.Path = ((env == 'p') ? "LDAP://RESOURCES.BPMGRP.GLOBAL" : "LDAP://RISORSELAB.BPMGRPLAB.GLOBAL");
            ldapConnection.AuthenticationType = AuthenticationTypes.Secure; 
            return ldapConnection;
        }

        static DirectoryEntry createAccountDirectoryEntry()
        {
            // create and return new LDAP connection with desired settings
            DirectoryEntry ldapConnection = new DirectoryEntry();
            String ADEntry = System.Environment.GetEnvironmentVariable("USERDNSDOMAIN");
            ldapConnection.Path = ((env == 'p') ? "LDAP://" + ADEntry : "LDAP://USERSLAB.BPMGRPLAB.GLOBAL");
            ldapConnection.AuthenticationType = AuthenticationTypes.Secure;
            if (env == 'p')
            {
                //produzione
                ldapConnection.Username = "USSUPAD";                
                ldapConnection.Password = "Password02";
            }
            else 
            { 
                //collaudo
                Console.WriteLine("Accesso al collaudo con userid e password");
                Console.Write("Inserisci l'utente per l'accesso su dominio account per l'AD (default battere invio: USSUPDAD) >>>");
                String user = Console.ReadLine();
                ldapConnection.Username = ("".Equals(user.Trim()))?"USSUPDAD":user;
                Console.Write("Inserisci password per l'accesso su dominio account per l'AD (deafult battere invio) >>>");
                String pwd = Console.ReadLine();
                ldapConnection.Password = ("".Equals(pwd.Trim())) ? "Password01" : pwd;
            }
            return ldapConnection;
        }

        static bool isAgrChannel(String agrDnToMatch) 
        {
            return (agrDnToMatch.ToUpper().Contains("01AGENZIA"));
        }
        /*
        static bool isOuPcInmM(String ouPc) 
        {
            //carico le info da file
            StreamReader objReader = null;
            try
            {
                objReader = new StreamReader("GER01HUB.xml");
                String sLine = "";
                StringBuilder hAndS = new StringBuilder();
                while (sLine != null)
                {
                    sLine = objReader.ReadLine();
                    if (sLine != null)
                        hAndS.Append(sLine);
                }
                return (hAndS.ToString().IndexOf(ouPc)) != -1;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
            finally
            {
                if (objReader!= null) objReader.Close();
            }
            return false;
        }*/
    }
}
